#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "base.h"

#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#else
#include <sys/time.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "sql/charset.h"
//#include <iconv.h>
#include <ctype.h>
#include <time.h>
#include "common_define.h"


namespace common
{
#ifdef _MSC_VER
	int gettimeofday(struct timeval *tp, void *tzp)
	{
		time_t clock;
		struct tm tm;
		SYSTEMTIME wtm;
		GetLocalTime(&wtm);
		tm.tm_year = wtm.wYear - 1900;
		tm.tm_mon = wtm.wMonth - 1;
		tm.tm_mday = wtm.wDay;
		tm.tm_hour = wtm.wHour;
		tm.tm_min = wtm.wMinute;
		tm.tm_sec = wtm.wSecond;
		tm.tm_isdst = -1;
		clock = mktime(&tm);
		tp->tv_sec = clock;
		tp->tv_usec = wtm.wMilliseconds * 1000;
		return (0);
	}
#else
	static struct timezone tz;
#endif

	int32_t SetUTCAndLocalDiff( )
	{
		struct timeval tv;
#ifdef _MSC_VER
		gettimeofday(&tv, NULL);
#else
		gettimeofday(&tv, &tz);
#endif
		
		return 0;
	}


#ifdef _MSC_VER

#else
	static int32_t Fls(int32_t x)
	{
		int r;
		__asm__("bsrl %1,%0\n\t"
			"jnz 1f\n\t"
			"movl $-1,%0\n"
			"1:" : "=r"(r) : "rm"(x));
		return r + 1;
	}

	uint32_t RoundupPowOfTwo(uint32_t value)
	{
		return 1 << Fls(value - 1);
	}
#endif

	time_t RebuildTime( struct tm* tm, int HH24MISS )
	{
		if ( NULL == tm )
		{
			return 0;
		}
		tm->tm_hour = HH24MISS / 10000;
		tm->tm_min = HH24MISS / 100 % 100;
		tm->tm_sec = HH24MISS % 100;
		return mktime( tm );
	}

	time_t RebuildTime( int YYYYMMDD, int HH24MISS )
	{
		struct tm rebuild;
		rebuild.tm_year = YYYYMMDD / 10000 - 1900;
		rebuild.tm_mon = YYYYMMDD / 100 % 100 - 1;
		rebuild.tm_mday = YYYYMMDD % 100;
		rebuild.tm_hour = HH24MISS / 10000;
		rebuild.tm_min = HH24MISS / 100 % 100;
		rebuild.tm_sec = HH24MISS % 100;
		return mktime( &rebuild );
	}

	time_t GetWeekTime( time_t ti )
	{
		struct tm *tm = localtime( &ti );
		if ( tm == NULL )
		{
			return 0;
		}
		tm->tm_wday = ( tm->tm_wday == 0 ) ? 6 : tm->tm_wday - 1;
		return ti - ( tm->tm_wday * 86400 + tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec );
	}

	time_t GetWeekSundyTime( time_t ti )
	{
		struct tm *tm = localtime( &ti );
		if ( tm == NULL )
		{
			return 0;
		}
		return ti - ( tm->tm_wday * 86400 + tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec );
	}

	int64_t GetCurrentMillisecond( )
	{
		struct timeval tv;
		gettimeofday( &tv, NULL );
		int64_t curms = tv.tv_sec;
		curms = curms * 1000 + tv.tv_usec / 1000;
		return curms;
		//return tv.tv_sec * 1000 + tv.tv_usec / 1000;
	}

	time_t GetCurrentSecond( )
	{
		return time( NULL );
	}

	int32_t GetWeekDay( time_t sec )
	{
		tm* t = localtime( &sec );	
		if( t == NULL )
		{
			return 0;
		}
		return t->tm_wday;
	}

	std::string GetSuffix(const std::string& str)
	{
		std::string suffix;
		std::string::size_type pos = str.rfind( "." );
		if ( pos != std::string::npos )
		{
			suffix = str.substr( pos + 1, str.length( ) - pos - 1 );
		}
		return suffix;
	}
}//namespace common
